﻿// Decompiled with JetBrains decompiler
// Type: System.Web.Razor.Text.LineTrackingStringBuffer
// Assembly: System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// MVID: 682513D6-F37E-48AC-9909-F3EE103CFF14
// Assembly location: D:\Project\Idea\无人机外网\uav\客户端工程\排查工具\bin\Release\System.Web.Razor.dll

using System.Collections.Generic;
using System.Text;
using System.Web.Razor.Parser;

namespace System.Web.Razor.Text
{
  internal class LineTrackingStringBuffer
  {
    private LineTrackingStringBuffer.TextLine _currentLine;
    private LineTrackingStringBuffer.TextLine _endLine;
    private IList<LineTrackingStringBuffer.TextLine> _lines;

    public LineTrackingStringBuffer()
    {
      this._endLine = new LineTrackingStringBuffer.TextLine(0, 0);
      this._lines = (IList<LineTrackingStringBuffer.TextLine>) new List<LineTrackingStringBuffer.TextLine>()
      {
        this._endLine
      };
    }

    public int Length => this._endLine.End;

    public SourceLocation EndLocation => new SourceLocation(this.Length, this._lines.Count - 1, this._lines[this._lines.Count - 1].Length);

    public void Append(string content)
    {
      for (int index = 0; index < content.Length; ++index)
      {
        this.AppendCore(content[index]);
        if (content[index] == '\r' && (index + 1 == content.Length || content[index + 1] != '\n') || content[index] != '\r' && ParserHelpers.IsNewLine(content[index]))
          this.PushNewLine();
      }
    }

    public LineTrackingStringBuffer.CharacterReference CharAt(
      int absoluteIndex)
    {
      LineTrackingStringBuffer.TextLine line = this.FindLine(absoluteIndex);
      if (line == null)
        throw new ArgumentOutOfRangeException(nameof (absoluteIndex));
      int num = absoluteIndex - line.Start;
      return new LineTrackingStringBuffer.CharacterReference(line.Content[num], new SourceLocation(absoluteIndex, line.Index, num));
    }

    private void PushNewLine()
    {
      this._endLine = new LineTrackingStringBuffer.TextLine(this._endLine.End, this._endLine.Index + 1);
      this._lines.Add(this._endLine);
    }

    private void AppendCore(char chr) => this._lines[this._lines.Count - 1].Content.Append(chr);

    private LineTrackingStringBuffer.TextLine FindLine(int absoluteIndex)
    {
      LineTrackingStringBuffer.TextLine textLine = (LineTrackingStringBuffer.TextLine) null;
      if (this._currentLine != null)
      {
        if (this._currentLine.Contains(absoluteIndex))
          textLine = this._currentLine;
        else if (absoluteIndex > this._currentLine.Index && this._currentLine.Index + 1 < this._lines.Count)
          textLine = this.ScanLines(absoluteIndex, this._currentLine.Index);
      }
      if (textLine == null)
        textLine = this.ScanLines(absoluteIndex, 0);
      this._currentLine = textLine;
      return textLine;
    }

    private LineTrackingStringBuffer.TextLine ScanLines(
      int absoluteIndex,
      int startPos)
    {
      for (int index1 = 0; index1 < this._lines.Count; ++index1)
      {
        int index2 = (index1 + startPos) % this._lines.Count;
        if (this._lines[index2].Contains(absoluteIndex))
          return this._lines[index2];
      }
      return (LineTrackingStringBuffer.TextLine) null;
    }

    internal class CharacterReference
    {
      public CharacterReference(char character, SourceLocation location)
      {
        this.Character = character;
        this.Location = location;
      }

      public char Character { get; private set; }

      public SourceLocation Location { get; private set; }
    }

    private class TextLine
    {
      private StringBuilder _content = new StringBuilder();

      public TextLine(int start, int index)
      {
        this.Start = start;
        this.Index = index;
      }

      public StringBuilder Content => this._content;

      public int Length => this.Content.Length;

      public int Start { get; set; }

      public int Index { get; set; }

      public int End => this.Start + this.Length;

      public bool Contains(int index) => index < this.End && index >= this.Start;
    }
  }
}
